package appli.agentImpl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import system.agent.Agent;
import system.agent.CommunicationAgentInterface;
import system.util.Server;
import system.util.message.Message;
import system.util.message.RequestMessage;
import system.util.message.ResponseMessage;
import appli.product.Product;

/**
 * A Store is an agent who sell items to other agents.
 */
public class Store extends Agent {

	private enum State {Initial, Registering, Normal};
	
	private static final long serialVersionUID = 6572207195686135899L;

	/**
	 * Products that the store is selling
	 */
	private Map<String, Product> products;
	/**
	 * Current state of the agent
	 */
	private State currentState;
	
	public Store(String agentName, String host, int port) {
		super(agentName, host, port);
		this.products = new HashMap<String, Product>();
		this.currentState = State.Initial;
	}
	
	public Store(String agentName, String host, int port, List<Product> products) {
		this(agentName, host, port);
		for (Product p : products) {
			this.products.put(p.getName(), p);
		}
	}
	
	@Override
	public void main() {
		switch (this.currentState) {
			case Initial:
				//we move to the directory in order to register ourself
				if (OPTION) { 
					System.out.println("Magasin " + getAgentName() + " : part visiter l'annuaire");
				}
				currentState = State.Registering;
				move(Directory.directoryAddressHost, Directory.directoryAddressPort);
				break;
			case Registering:
				// Registering of the store to the directory
				if (OPTION) {
					System.out.println("Magasin " + getAgentName() + " : inscription auprés de l'annuaire");
				}
				CommunicationAgentInterface directory = Server.getAgent(Directory.directoryName);
				String msg = "REGISTERING" + Message.SEPARATOR + this.getAgentName() + Message.SEPARATOR + this.getInitialHost() + Message.SEPARATOR + this.getInitialPort();
				directory.handleMessage(new Message(directory.getAgentName(), msg));
				currentState = State.Normal;
				back();
				break;
			case Normal:
				// Waiting for buyers
				if (OPTION) {
					System.out.println("Magasin " + getAgentName() + " : en attente d'acheteurs");
				}
				Message m;
				while(true){
					m = waitForNextMessage();
					if(m != null)
						messageTraitment(m);
				}
		default:
			break;
		}
		
	}

	public Map<String, Product> getProducts() {
		return products;
	}

	public void setProducts(Map<String, Product> products) {
		this.products = products;
	}
	
	/**
	 * Treatment of the incoming messages
	 * @param m Message to deal with
	 */
	private void messageTraitment(Message m){
		try {
			String[] msg = m.getMessage();
			if(msg[0].equals("GET")){
				if(msg[1].equals("PRODUCTS")){
					if(msg[2].equals("LIST")){
						List<Product> copyOfProducts = new ArrayList<Product>();
						for(Product p : products.values())
							copyOfProducts.add(new Product(p.getName(), p.getQuantity(), p.getPrice()));
						ResponseMessage resp = ((RequestMessage)m).getFuture();
						resp.setData(copyOfProducts);
						resp.setMessage("SET" + Message.SEPARATOR + "PRODUCTS" + Message.SEPARATOR + "LIST");
					}
				}
			}
			else if(msg[0].equals("BUY")) {
				String productName = msg[1];
				int productQuantity = Integer.parseInt(msg[2]);
				Product old = products.get(productName);
				Product p = new Product(productName, productQuantity, old.getPrice());
				old.setQuantity(old.getQuantity() - productQuantity);
				ResponseMessage resp = ((RequestMessage)m).getFuture();
				resp.setData(p);
				resp.setMessage("BUY OK");
			}
		}
		catch (IndexOutOfBoundsException e) {
			e.printStackTrace();
		}
	}

}
